package com.example.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Date;
import java.util.Map;

/**
 * JWT工具类
 */
public class JwtUtil {

    private final SecretKey secretKey; // 密钥
    private final String issuer; // 签发者
    private final long expireMillis; // 过期时间，毫秒

    public JwtUtil(String secret, String issuer, long expireMinutes) {
        this.secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
        this.issuer = issuer;
        this.expireMillis = expireMinutes * 60_000L;
    }

    /**
     * 生成带自定义 claims 的 Access Token
     */
    public String generateToken(String subject, Map<String, Object> claims) {
        Instant now = Instant.now(); // 当前时间
        return Jwts.builder()
                .claims(claims) // 添加自定义 claims
                .subject(subject) // 设置令牌的主题为用户名
                .issuer(issuer) // 设置令牌的签发者
                .issuedAt(Date.from(now)) // 设置令牌的签发时间为当前时间
                .expiration(Date.from(now.plusMillis(expireMillis))) // 设置令牌的过期时间为当前时间加上配置的过期毫秒数
                .signWith(secretKey) // 签名
                .compact();
    }

    /**
     * 解析并验证签名（仅支持已签名的JWT），失败将抛出异常
     */
    public Claims parseAndValidate(String token) {
        return Jwts.parser()
                .verifyWith(secretKey)
                .requireIssuer(issuer)
                .build()
                .parseSignedClaims(token)
                .getPayload();
    }

    /**
     * 获取用户名
     */
    public String getUsername(String token) {
        return parseAndValidate(token).getSubject();
    }

}
